﻿Imports DevExpress.XtraScheduler.Services
Imports DevExpress.XtraScheduler.Commands

Public Class ActivitySchedulerForm
    Implements IReloadCommand


    Public Property Pl As PL.PLBase
    Public Property LabelQuery As MetaQuery
    Public Property RessourceQuery As MetaQuery
    Public Property FormCtrlCD As String
    Public Property CtrlName As String Implements IReloadCommand.CtrlName

    Public Property LastFetchedInterval As TimeInterval = New TimeInterval()
    Public Property GroupID As Guid?


    Public Property MainQueryName() As String
    Public WithEvents Dataset As DataSet
    Public WithEvents MetaDataTable As CommonExt.MetaDataTable

    Public Event AfterLoad(ByVal sender As Object, ByVal e As System.EventArgs)

    Private aSqlcmd As System.Data.SqlClient.SqlCommand


    Public WithEvents aEditFormAppointment As ActivityEditForm

    Private listOfLabel As Dictionary(Of Long, Guid) = New Dictionary(Of Long, Guid)

    Private listOfressource As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)
    Private listOfstatus As Dictionary(Of String, Guid) = New Dictionary(Of String, Guid)

    Public AllowCreate As Boolean
    Public AllowRead As Boolean
    Public AllowUpdate As Boolean
    Public AllowDelete As Boolean

    Private Property appointment As Appointment

    Dim aTable As MetaQuery

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        AllowCreate = True
        AllowRead = True
        AllowUpdate = True
        AllowDelete = True
        '
    End Sub

    Private Sub Scheduler_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        SchedulerControl1.Start = Today

        LoadSchedule()
        SchedulerControl1.Storage = SchedulerStorage1
        DateNavigator1.SchedulerControl = SchedulerControl1
    End Sub

    Private Function InitData() As DialogResult
        Dim aParamFrm As MqParamForm
        Dim aExecQuery As DialogResult = DialogResult.OK
        Dim aMq As MetaQuery = MetaQuery.GetMetaQueryByName(Pl.QueryName)
        Dim reader As SqlClient.SqlDataReader = Nothing
        Dim aDataRow As DataRow
        '
        SchedulerStorage1.Appointments.Clear()
        SchedulerStorage1.Appointments.DataSource = Nothing
        If Pl.Dataset.Tables.Contains(Pl.MetaDataTable.TableName) Then
            Pl.Dataset.Tables.Remove(Pl.MetaDataTable)
        End If
        Pl.Dataset.Clear()
        Pl.MetaDataTable.Clear()
        '
        If aMq.CommandTypeID = CommonExt.Base.IdRepository.METALIST_METACOMMANDTYPE_SP AndAlso aMq.MetaParams.Rows.Count > 0 Then
            aParamFrm = New MqParamForm(aMq.QueryName)
            aExecQuery = aParamFrm.ShowDialog()
            'On dit OK pour la form de Parametre
            If aExecQuery = DialogResult.OK Then
                '
                aSqlcmd = aMq.InitQueryParams
                Dim param As SqlClient.SqlParameter
                For Each row As DataRow In aMq.MetaParams.Rows
                    If aSqlcmd.Parameters.Contains(row("ColumnName").ToString) Then
                        param = aSqlcmd.Parameters(row("ColumnName").ToString)
                        If param IsNot Nothing AndAlso param.ParameterName = "@GroupId_FK" AndAlso Not IsDBNull(aParamFrm.SelectedParam(row("ColumnName").ToString)) Then
                            param.Value = aParamFrm.SelectedParam(row("ColumnName").ToString)
                            GroupID = CType(IIf(param.Value IsNot Nothing, Guid.Parse(param.Value.ToString), Nothing), Guid)
                            aDataRow = SystemBoxSDK.PL.CoreSDK.ListValues_PL.GetListValueByID(CType(GroupID, Guid))
                            If aDataRow IsNot Nothing Then
                                Me.Text = String.Format("{0} {1}", "Schedule for : ", aDataRow("Value_PRM"))
                            Else
                                Me.Text = String.Format("{0} {1}", "Schedule for : ", "All Groups")
                            End If
                        End If
                    Else
                        MessageWindow.ShowMessage(New Exception(String.Format("Scheduler execution, SQL Parameter not found: {0}", row("ColumnName"))))
                    End If
                Next
                '
                'On Passe la sqcmd qui a les paramêtre de rentré
                Pl.MetaDataTable.GetMetaCommand()
                LoadAppointmentinfo(True, DateTime.Today, DateTime.Today)
                Pl.Dataset.Tables.Add(Pl.MetaDataTable)
                '
            ElseIf aExecQuery = DialogResult.Cancel Then
                'More to come...
            End If
        End If
        Return aExecQuery
    End Function

    Public Sub ApplyStorageMapping()
        '
        Dim label As Integer

        SchedulerControl1.UseWaitCursor = True
        SchedulerControl1.Refresh()

        Me.SchedulerControl1.BeginUpdate()
        SchedulerStorage1.Appointments.DataSource = Pl.Dataset.Tables(0).DefaultView
        '
        Me.SchedulerStorage1.Appointments.Labels.Clear()
        LabelQuery = MetaQuery.GetMetaQueryByName("AppointmentLabel")
        '
        LabelQuery.FillResultQuery()
        listOfLabel.Clear()
        '
        For Each row As DataRow In LabelQuery.ResultQuery.Rows
            label = Me.SchedulerStorage1.Appointments.Labels.Add(SetColor(row("color")), row("MenuCaption").ToString, row("MenuCaption").ToString)
            listOfLabel.Add(label, New Guid(row("Id").ToString))
        Next
        '
        SchedulerStorage1.Appointments.Mappings.AppointmentId = "Id"
        SchedulerStorage1.Appointments.Mappings.AllDay = "AllDayEvent"
        SchedulerStorage1.Appointments.Mappings.Description = "Body"
        SchedulerStorage1.Appointments.Mappings.Label = "Labelint"
        SchedulerStorage1.Appointments.Mappings.Subject = "Subject"
        SchedulerStorage1.Appointments.Mappings.Location = "Location"
        SchedulerStorage1.Appointments.Mappings.Start = "Start"
        SchedulerStorage1.Appointments.Mappings.End = "End"
        '  Me.SchedulerStorage1.Appointments.Mappings.Status = "Status"
        ' Me.SchedulerStorage1.Appointments.Mappings.Type = "Type"

        Me.SchedulerStorage1.Appointments.CustomFieldMappings.Add(New AppointmentCustomFieldMapping("CustomGroupId", "GroupId_FK"))
        Me.SchedulerStorage1.Appointments.CustomFieldMappings.Add(New AppointmentCustomFieldMapping("CustomClassId", "ClassId_FK"))
        Me.SchedulerStorage1.Appointments.CustomFieldMappings.Add(New AppointmentCustomFieldMapping("CustomCategoryId", "CategoryId_FK"))
        Me.SchedulerStorage1.Appointments.CustomFieldMappings.Add(New AppointmentCustomFieldMapping("CustomTypeId", "TypeId_FK"))

        Me.SchedulerControl1.EndUpdate()
        '
        SchedulerControl1.UseWaitCursor = False

    End Sub


    Public Shared Function SetColor(ByVal afield As Object) As System.Drawing.Color
        If afield IsNot Nothing AndAlso Not IsDBNull(afield) Then
            If CType(afield, Decimal) = 0 Then
                Return System.Drawing.Color.FromArgb(CInt(afield))
            Else
                Return System.Drawing.Color.FromArgb(CInt(afield))
            End If

        End If
    End Function

    Private Sub SchedulerStorage1_AppointmentChanging(sender As Object, e As DevExpress.XtraScheduler.PersistentObjectCancelEventArgs) Handles SchedulerStorage1.AppointmentChanging
        Dim aAppt As Appointment = TryCast(e.Object, Appointment)
        Dim aDataRowView As DataRowView
        Dim aRow As DataRow
        If aAppt IsNot Nothing Then
            aDataRowView = TryCast(aAppt.GetRow(SchedulerStorage1), DataRowView)
            If aDataRowView IsNot Nothing Then
                aRow = aDataRowView.Row
                If aRow IsNot Nothing Then
                    'aRow("LabelId_FK") = listOfLabel(CLng(aRow("Labelint")))
                    'Pl.Save()
                    'OutStandingIssue: A finir.
                    'Pl.ValidateRow(aRow)
                    'If aRow.HasErrors Then
                    '    e.Cancel = True
                    'End If
                End If
            End If
        End If

    End Sub

    Private Sub SchedulerStorage1_AppointmentsInserted(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsInserted
        Dim aAppt As Appointment = TryCast(e.Objects(0), Appointment)
        Dim aRow As DataRow
        Dim aDataRowView As DataRowView
        If aAppt IsNot Nothing Then
            SchedulerControl1.BeginUpdate()
            aDataRowView = TryCast(aAppt.GetRow(SchedulerStorage1), DataRowView)
            If aDataRowView IsNot Nothing Then
                aRow = aDataRowView.Row
                If aRow IsNot Nothing Then
                    aRow("Id") = aAppt.Id
                    aRow("LabelId_FK") = listOfLabel(CLng(aRow("Labelint")))
                    Pl.Save()
                    LastFetchedInterval = New TimeInterval()
                    Pl.MetaDataTable.Clear()
                End If
            End If
            SchedulerControl1.EndUpdate()
        End If
    End Sub

    Private Sub SchedulerStorage1_AppointmentsChanged(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsChanged
        Dim aAppt As Appointment = TryCast(e.Objects(0), Appointment)
        Dim aRow As DataRow
        Dim aDataRowView As DataRowView
        If aAppt IsNot Nothing Then
            SchedulerControl1.BeginUpdate()
            aDataRowView = TryCast(aAppt.GetRow(SchedulerStorage1), DataRowView)
            If aDataRowView IsNot Nothing Then
                aRow = aDataRowView.Row
                If aRow IsNot Nothing Then
                    aRow("LabelId_FK") = listOfLabel(CLng(aRow("Labelint")))
                    Pl.Save()
                    LastFetchedInterval = New TimeInterval()
                    Pl.MetaDataTable.Clear()
                End If
            End If
            SchedulerControl1.EndUpdate()
        End If
    End Sub

    Private Sub SchedulerStorage1_AppointmentsDeleted(sender As Object, e As PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsDeleted
        Dim aAppt As Appointment = CType(e.Objects(0), Appointment)
        Dim aRow As DataRow
        Dim aDataRowView As DataRowView
        If aAppt IsNot Nothing Then
            SchedulerControl1.BeginUpdate()
            aDataRowView = TryCast(aAppt.GetRow(SchedulerStorage1), DataRowView)
            If aDataRowView IsNot Nothing Then
                aRow = aDataRowView.Row
                If aRow IsNot Nothing Then
                    aRow.Delete()
                    Pl.Save()
                    LastFetchedInterval = New TimeInterval()
                    Pl.MetaDataTable.Clear()
                End If
            End If
            SchedulerControl1.EndUpdate()
        End If
    End Sub

    Public Sub ReloadCommand() Implements CommonExt.IReloadCommand.ReloadCommand
        LoadSchedule()
    End Sub


    '' Customize the popup menu. 
    Private Sub schedulerControl1_PopupMenuShowing(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PopupMenuShowingEventArgs) Handles SchedulerControl1.PopupMenuShowing

        Dim aCopyItem As SchedulerMenuItem
        Dim aCutItem As SchedulerMenuItem
        Dim aPasteItem As SchedulerMenuItem

        If e.Menu.Id = DevExpress.XtraScheduler.SchedulerMenuItemId.DefaultMenu Then
            Dim item As DevExpress.XtraScheduler.SchedulerMenuItem = e.Menu.GetMenuItemById(DevExpress.XtraScheduler.SchedulerMenuItemId.NewAppointment)
            If Not (item Is Nothing) Then
                ' Rename the menu item for the 'New Appointment' action. 
                item.Caption = "Open My Appointment Form"
            End If
            aPasteItem = New SchedulerMenuItem("Paste", AddressOf PasteAppt)
            aPasteItem.BeginGroup = True
            If appointment Is Nothing Then
                aPasteItem.Enabled = False
            End If
            e.Menu.Items.Add(aPasteItem)
        End If

        If e.Menu.Id = DevExpress.XtraScheduler.SchedulerMenuItemId.AppointmentMenu Then
            ' Insert a new item into the Scheduler popup menu and handle its click event.
            aCopyItem = New SchedulerMenuItem("Copy", AddressOf CopyAppt)
            aCopyItem.BeginGroup = True
            e.Menu.Items.Add(aCopyItem)
            aCutItem = New SchedulerMenuItem("Cut", AddressOf CutAppt)
            e.Menu.Items.Add(aCutItem)
        End If
    End Sub


    Public Sub CopyAppt(ByVal sender As Object, ByVal e As EventArgs)
        appointment = SchedulerControl1.SelectedAppointments(0).Copy
    End Sub
    Public Sub CutAppt(ByVal sender As Object, ByVal e As EventArgs)
        appointment = SchedulerControl1.SelectedAppointments(0).Copy
        SchedulerControl1.SelectedAppointments(0).Delete()
    End Sub
    Public Sub PasteAppt(ByVal sender As Object, ByVal e As EventArgs)
        Dim newAppt As Appointment
        If appointment IsNot Nothing Then
            newAppt = appointment.Copy
            SchedulerStorage1.SetAppointmentId(newAppt, Guid.NewGuid)
            newAppt.Start = SchedulerControl1.SelectedInterval.Start
            newAppt.End = SchedulerControl1.SelectedInterval.Start
            SchedulerStorage1.Appointments.Add(newAppt)
        End If
    End Sub

    Private Sub schedulerControl_EditAppointmentFormShowing(ByVal sender As Object, ByVal e As AppointmentFormEventArgs) Handles SchedulerControl1.EditAppointmentFormShowing
        Dim apt As Appointment = e.Appointment
        ' Required to open the recurrence form via context menu.
        'Dim openRecurrenceForm As Boolean = apt.IsRecurring AndAlso SchedulerStorage1.Appointments.IsNewAppointment(apt)
        '' Create a custom form.
        aEditFormAppointment = New ActivityEditForm(CType(sender, SchedulerControl), apt)

        If GroupID Is Nothing Then
            aEditFormAppointment.LockGroup = False
        Else
            aEditFormAppointment.LockGroup = True
        End If

        aEditFormAppointment.Update()
        Try
            ' Required for skins support.
            aEditFormAppointment.LookAndFeel.ParentLookAndFeel = SchedulerControl1.LookAndFeel

            e.DialogResult = aEditFormAppointment.ShowDialog()
            SchedulerControl1.Refresh()
            e.Handled = True
        Finally
            aEditFormAppointment.Dispose()
        End Try
    End Sub

    Private Sub SchedulerControl1_InitNewAppointment(sender As Object, e As AppointmentEventArgs) Handles SchedulerControl1.InitNewAppointment
        e.Appointment.CustomFields("CustomGroupId") = GroupID
        e.Appointment.CustomFields("CustomClassId") = Nothing
        e.Appointment.CustomFields("CustomCategoryId") = Nothing
        e.Appointment.CustomFields("CustomTypeId") = Nothing
    End Sub

    Private Sub LoadButtonItem1_ItemClick(sender As Object, e As ItemClickEventArgs) Handles LoadButtonItem1.ItemClick
        LoadSchedule()
    End Sub

    Private Sub LoadSchedule()
        LastFetchedInterval = New TimeInterval()
        If InitData() = Windows.Forms.DialogResult.OK Then
            Me.Cursor = Cursors.WaitCursor
            ApplyStorageMapping()
            SchedulerControl1.Visible = True
            SplitContainerControl1.Visible = True
            DateNavigator1.Visible = True
            Me.Cursor = Cursors.Default
        Else
            SchedulerControl1.Visible = False
            DateNavigator1.Visible = False
            SplitContainerControl1.Visible = False
        End If
    End Sub


    Private Sub SchedulerStorage1_FetchAppointments(sender As Object, e As FetchAppointmentsEventArgs) Handles SchedulerStorage1.FetchAppointments
        Dim aStart As DateTime = e.Interval.Start
        Dim aEnd As DateTime = e.Interval.End

        ' Check if the requested interval is outside lastFetchedInterval
        If ((aStart <= LastFetchedInterval.Start) OrElse (aEnd >= LastFetchedInterval.End)) Then
            '
            LastFetchedInterval = New TimeInterval((aStart - TimeSpan.FromDays(14)), (aEnd + TimeSpan.FromDays(14)))
            ' Load Data
            LoadAppointmentinfo(False, aStart, aEnd)
        End If
    End Sub


    Private Sub LoadAppointmentinfo(ByVal InitEmpty As Boolean, ByVal startdate As DateTime, ByVal enddate As DateTime)
        SchedulerControl1.BeginUpdate()
        Pl.MetaDataTable.Clear()
        'On Passe la sqcmd qui a les paramêtre de rentré
        Pl.MetaDataTable.GetMetaCommand()
        '
        aSqlcmd.Parameters("@Start").Value = startdate
        aSqlcmd.Parameters("@End").Value = enddate
        aSqlcmd.Parameters("@GroupId_FK").Value = IIf(InitEmpty, Guid.Empty, GroupID)
        '
        Pl.MetaDataTable.FillResultQuery(SqlCmd:=aSqlcmd)
        SchedulerControl1.EndUpdate()
    End Sub
End Class